package com.shrct.businessprocess.purchase.impl;

import com.google.common.collect.Iterables;
import com.shrct.businessprocess.money.Moneys;
import com.shrct.businessprocess.project.RCExchangeRate;
import com.shrct.businessprocess.project.RCProjectMoney;
import com.shrct.businessprocess.purchase.RCBasePurchaseOrder;
import com.shrct.businessprocess.purchase.RCBasePurchaseOrderAccept;
import com.shrct.businessprocess.purchase.RCBasePurchasePayRequest;
import com.shrct.businessprocess.purchase.RCPurchaseOrderAcceptPay;
import com.shrct.businessprocess.purchase.RCPurchaseOrderAcceptPayDAO;
import com.shrct.businessprocess.purchase.RCPurchasePayRequest;
import com.shrct.businessprocess.purchase.proxy.RCBasePurchaseOrderAcceptProxy;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.hibernate.annotations.DiscriminatorOptions;
import org.springframework.beans.factory.BeanFactory;

@Entity
@DiscriminatorValue("RCBASEPURCHASEORDERACCEPT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcbasepurchaseorderaccept")
public abstract class RCBasePurchaseOrderAcceptImpl extends BaseModelObject implements RCBasePurchaseOrderAccept {
  public RCBasePurchaseOrderAcceptImpl() {
    super();
  }
  
  private Date date;
  
  public Date getDate() {
    return this.date;
  }
  
  public RCBasePurchaseOrderAccept setDate(final Date date) {
    this.date = date;
    return this;			
    
  }
  
  private Date termDate;
  
  public Date getTermDate() {
    return this.termDate;
  }
  
  public RCBasePurchaseOrderAccept setTermDate(final Date termDate) {
    this.termDate = termDate;
    return this;			
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public RCBasePurchaseOrderAccept setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  public Collection<RCPurchaseOrderAcceptPay> getPays() {
    IGenericQuery<RCPurchaseOrderAcceptPay> query=getObjectFactory().createGenericQuery(RCPurchaseOrderAcceptPay.class,"select pay from com.shrct.businessprocess.purchase.impl.RCPurchaseOrderAcceptPayImpl as pay   where ((pay.accept) = (:this)) and  pay.active = 1      ").setParameter("this",this);
    Collection<RCPurchaseOrderAcceptPay> _list = query.list();
    return _list;
  }
  
  /**
   * 已支付金额
   */
  public RCProjectMoney getTotalPaidAmount() {
    Collection<RCPurchaseOrderAcceptPay> _pays = this.getPays();
    final Function1<RCPurchaseOrderAcceptPay,RCProjectMoney> _function = new Function1<RCPurchaseOrderAcceptPay,RCProjectMoney>() {
        public RCProjectMoney apply(final RCPurchaseOrderAcceptPay it) {
          RCProjectMoney _amount = it.getAmount();
          return _amount;
        }
      };
    Iterable<RCProjectMoney> _map = IterableExtensions.<RCPurchaseOrderAcceptPay, RCProjectMoney>map(_pays, _function);
    RCBasePurchaseOrder _purchaseOrder = this.getPurchaseOrder();
    RCExchangeRate _defaultExchangeRate = _purchaseOrder.getDefaultExchangeRate();
    RCProjectMoney _sum = Moneys.sum(_map, _defaultExchangeRate);
    return _sum;
  }
  
  public Boolean getIsTotalPaid() {
    RCProjectMoney _totalPaidAmount = this.getTotalPaidAmount();
    Double _hostAmount = _totalPaidAmount.toHostAmount();
    RCProjectMoney _totalAmount = this.getTotalAmount();
    Double _hostAmount_1 = _totalAmount.toHostAmount();
    boolean _greaterEqualsThan = (_hostAmount.compareTo(_hostAmount_1) >= 0);
    return Boolean.valueOf(_greaterEqualsThan);
  }
  
  public Boolean isTermOverDue() {
    boolean _and = false;
    Boolean _isTotalPaid = this.getIsTotalPaid();
    boolean _not = (!_isTotalPaid);
    if (!_not) {
      _and = false;
    } else {
      Date _day = DateUtil.today();
      long _time = _day.getTime();
      long _time_1 = this.termDate.getTime();
      boolean _greaterEqualsThan = (_time >= _time_1);
      _and = (_not && _greaterEqualsThan);
    }
    return Boolean.valueOf(_and);
  }
  
  /**
   * 尝试从已付款中选取费用作为本次收货的欠款
   */
  public void pay(final RCProjectMoney payAmount) {
    RCProjectMoney toPaid = payAmount;
    BeanFactory _beanFactory = this.getBeanFactory();
    final RCPurchaseOrderAcceptPayDAO dao = _beanFactory.<RCPurchaseOrderAcceptPayDAO>getBean(RCPurchaseOrderAcceptPayDAO.class);
    RCBasePurchaseOrder _purchaseOrder = this.getPurchaseOrder();
    Collection<RCBasePurchasePayRequest> _payRequests = _purchaseOrder.getPayRequests();
    Iterable<RCPurchasePayRequest> _filter = Iterables.<RCPurchasePayRequest>filter(_payRequests, RCPurchasePayRequest.class);
    for (final RCPurchasePayRequest payRequest : _filter) {
      {
        RCProjectMoney _totalPaidProjectAmount = payRequest.getTotalPaidProjectAmount();
        RCProjectMoney _usedAmount = payRequest.getUsedAmount();
        RCProjectMoney remained = _totalPaidProjectAmount.substract(_usedAmount);
        boolean _and = false;
        Double _amount = toPaid.getAmount();
        boolean _greaterThan = ((_amount).doubleValue() > 0);
        if (!_greaterThan) {
          _and = false;
        } else {
          Double _amount_1 = remained.getAmount();
          boolean _greaterThan_1 = ((_amount_1).doubleValue() > 0);
          _and = (_greaterThan && _greaterThan_1);
        }
        if (_and) {
          final RCProjectMoney canTakeFrom = remained.canTake(toPaid);
          Double _amount_2 = canTakeFrom.getAmount();
          boolean _greaterThan_2 = ((_amount_2).doubleValue() > 0);
          if (_greaterThan_2) {
            dao.create(this, payRequest, canTakeFrom);
          }
          RCProjectMoney _substract = toPaid.substract(canTakeFrom);
          toPaid = _substract;
        }
      }
    }
  }
  
  /**
   * 尝试从已付款中选取费用作为本次收货的所有欠款
   */
  public void pay() {
    RCProjectMoney _totalAmount = this.getTotalAmount();
    RCProjectMoney _totalPaidAmount = this.getTotalPaidAmount();
    RCProjectMoney _neg = _totalPaidAmount.neg();
    RCProjectMoney _plus = _totalAmount.plus(_neg);
    this.pay(_plus);
  }
  
  public RCBasePurchaseOrderAcceptProxy toProxy() {
    com.shrct.businessprocess.purchase.proxy.RCBasePurchaseOrderAcceptProxy proxy = new com.shrct.businessprocess.purchase.proxy.RCBasePurchaseOrderAcceptProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
